/**
 * @file main.cpp
 *
 * Copyright (C) 2024. Huawei Technologies Co., Ltd. All rights reserved.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 */
#include "whole_reduce_sum_tiling.h"
#include "data_utils.h"

#include "acl/acl.h"
#include "aclrtlaunch_whole_reduce_sum.h"

#include "tiling/platform/platform_ascendc.h"
#include "shape_config.h"

const uint32_t BLOCK_SIZE = 32;
const uint32_t BUFFER_NUM = 1; //回归的不用double buffer


int32_t main(int32_t argc, char *argv[])
{
    uint32_t blockDim = 1;
    //aclrtAPI要用
    size_t inputByteSize = INPUT_SHAPE[0] * INPUT_SHAPE[1] * sizeof(uint16_t);  
    size_t outputByteSize = INPUT_SHAPE[0] * sizeof(uint16_t);


    CHECK_ACL(aclInit(nullptr));
    int32_t deviceId = 0;
    CHECK_ACL(aclrtSetDevice(deviceId));
    aclrtStream stream = nullptr;
    CHECK_ACL(aclrtCreateStream(&stream));

    WholeReduceSumTilingData *tiling;
    uint8_t *xHost, *zHost;
    uint8_t *xDevice, *zDevice;

    CHECK_ACL(aclrtMallocHost((void **)(&tiling), sizeof(WholeReduceSumTilingData)));
    uint32_t coreInputDataNum = INPUT_SHAPE[0] * INPUT_SHAPE[1];
    uint32_t coreOutputDataNum = INPUT_SHAPE[0];

    tiling->coreInputDataNum = coreInputDataNum;
    tiling->coreOutputDataNum = coreOutputDataNum;

    CHECK_ACL(aclrtMallocHost((void **)(&xHost), inputByteSize));
    
    CHECK_ACL(aclrtMallocHost((void **)(&zHost), outputByteSize));
    CHECK_ACL(aclrtMalloc((void **)&xDevice, inputByteSize, ACL_MEM_MALLOC_HUGE_FIRST));
    
    CHECK_ACL(aclrtMalloc((void **)&zDevice, outputByteSize, ACL_MEM_MALLOC_HUGE_FIRST));

    ReadFile("./input/input_x.bin", inputByteSize, xHost, inputByteSize);
    

    CHECK_ACL(aclrtMemcpy(xDevice, inputByteSize, xHost, inputByteSize, ACL_MEMCPY_HOST_TO_DEVICE));
    

        
    ACLRT_LAUNCH_KERNEL(whole_reduce_sum)(blockDim, stream, xDevice, zDevice, tiling);
    CHECK_ACL(aclrtSynchronizeStream(stream));

    CHECK_ACL(aclrtMemcpy(zHost, outputByteSize, zDevice, outputByteSize, ACL_MEMCPY_DEVICE_TO_HOST));
    WriteFile("./output/output_z.bin", zHost, outputByteSize);

    CHECK_ACL(aclrtFree(xDevice));
    
    CHECK_ACL(aclrtFree(zDevice));
    CHECK_ACL(aclrtFreeHost(xHost));
    
    CHECK_ACL(aclrtFreeHost(zHost));
    CHECK_ACL(aclrtFreeHost(tiling));

    CHECK_ACL(aclrtDestroyStream(stream));
    CHECK_ACL(aclrtResetDevice(deviceId));
    CHECK_ACL(aclFinalize());

    return 0;
}
